package emulator.shell.commands;

import emulator.EmulatorException;
import emulator.hardware.memory.DebugMemoryInterface;
import emulator.shell.DebugShell;
import emulator.shell.ShellCommand;
import emulator.util.AddressRange;

public class Watch implements ShellCommand {

	@Override
	public boolean execute(DebugShell shell, String[] arg)
			throws EmulatorException {
		if (arg.length < 2)
			shell.getOut().println("Missing watch type!");
		else
		{
			boolean watch_read = false;
			boolean watch_write = false;
			boolean watch_set = true;
			if (arg[1].equalsIgnoreCase("write"))
				watch_write = true;
			else if (arg[1].equalsIgnoreCase("read"))
				watch_read = true;
			else if (arg[1].equalsIgnoreCase("clear"))
			{
				watch_write = true;
				watch_read = true;
				watch_set = false;
			}
			else
			{
				shell.getOut().println("Don't know how to watch \""+arg[1]+"\"");
				return false;
			}
			if (arg.length < 3)
				shell.getOut().println("Missing range!");
			else
			{
				try {
					DebugMemoryInterface memory = (DebugMemoryInterface) shell.getMemory();
					AddressRange range = AddressRange.fromString(arg[2]);
					if (watch_read)
						memory.enableReadWatch(range.getStart(), range.getEnd(), watch_set);
					if (watch_write)
						memory.enableWriteWatch(range.getStart(), range.getEnd(), watch_set);
				} catch (NumberFormatException e) {
					shell.getOut().println("Illegal argument: "+e.getMessage());
				} catch (ClassCastException e) {
					shell.getOut().println("Memory does not support watching.");
				}
			}
		}
		
		return false;
	}

	@Override
	public void printHelp(DebugShell shell) {
		shell.getOut().println("command syntax:");
		shell.getOut().println("watch write <address> - break on memory write at <address>");
		shell.getOut().println("watch read <address>  - break on memory read at <address>");
		shell.getOut().println("watch clear <address> - clear memory watch");
	}
}
